
//
//  stack.cpp
//  learnC++
//
//  Created by apple on 2018/6/1.
//  Copyright © 2018年 yunfan.com. All rights reserved.
//

#include "stack.hpp"


//一：
//调用堆栈（通常称为“堆栈”）具有更有趣的作用。调用堆栈会记录从程序开始到当前执行点的所有活动函数（已被调用但尚未终止的函数），并处理所有函数参数和局部变量的分配。

//二：调用堆栈段
//调用堆栈段保存用于调用堆栈的内存。当应用程序启动时，操作系统会将main（）函数压入调用堆栈。然后程序开始执行。
//遇到函数调用时，函数被压入调用堆栈。当前函数结束时，该函数将从调用堆栈中弹出。因此，通过查看在调用堆栈上推送的函数，我们可以看到所有调用的函数到达当前的执行点。

//三：调用堆栈正在运行
//让我们更详细地研究调用堆栈的工作原理。这是调用函数时发生的一系列步骤：
//程序遇到函数调用。
//堆栈框架被构建并被推入堆栈。堆栈帧包括：
//超出函数调用的指令地址（称为返回地址）。这就是CPU在被调用函数退出之后记得回到哪里的方式。
//所有函数参数。
//内存用于任何局部变量。
//当函数返回时，由函数修改的任何寄存器的已保存副本都需要恢复
//CPU跳转到函数的起点。
//函数内部的指令开始执行。
//当函数终止时，将发生以下步骤：
//寄存器从调用堆栈中恢复
//堆栈框架弹出堆栈。这为所有局部变量和参数释放内存。
//处理返回值。
//CPU在返回地址恢复执行。
//根据计算机的体系结构，可以用多种不同的方式处理返回值。一些体系结构将返回值作为堆栈框架的一部分。其他人使用CPU寄存器。
//通常，了解有关调用堆栈如何工作的所有细节并不重要。但是，理解函数在被调用时被有效地压入堆栈并在返回时弹出，这为您提供了理解递归所需的基础知识，以及其他一些在调试时很有用的概念。
//技术说明：在某些体系结构中，调用堆栈从内存地址0开始增长。在另一些体系结构中，它向内存地址0增长。因此，新推入的堆栈帧可能具有比以前更高或更低的内存地址。

//Example

//int foo(int x)
//{
//    // b
//    return x;
//} // foo is popped off the call stack here

//int main()
//{
//    // a
//    foo(5); // foo is pushed on the call stack here
//    // c
//
//    return 0;
//}

//The call stack looks like the following at the labeled points:
//a:
//main()

//b:
//foo11() (including parameter x)
//main()

//c:
//main()

